package org.lanyu.springainovel.chat.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.lanyu.springainovel.common.entity.AiMcp;
import org.lanyu.springainovel.common.service.AiMcpService;
import org.lanyu.springainovel.common.service.DynamicMcpClientManager;
import org.lanyu.springainovel.common.vo.RestVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * MCP工具控制�?- Spring AI 1.0.0完整版本
 * 
 * <p>提供统一的REST API来调用MCP工具，支持工具发现、状态查询和动态刷�? *
 * @author Spring AI Team
 * @since 1.1.0
 */
@Tag(name = "mcp工具", description = "供统一的REST API来调用MCP工具")
@RestController
@RequestMapping("/mcp")
public class McpToolController {

    private static final Logger logger = LoggerFactory.getLogger(McpToolController.class);
    
    /**
     * AiMcpService，负责MCP工具的数据库操作
     */
    @Autowired
    private AiMcpService aiMcpService;
    
    /**
     * DynamicMcpClientManager，负责MCP客户端管�?     */
    @Autowired
    private DynamicMcpClientManager dynamicMcpClientManager;

    public McpToolController() {
        super(); // 默认无参构造，调用父类构造函�?
    }

    /**
     * 分页查询MCP工具，支持名称和描述模糊搜索，按添加日期倒序
     */
    @Operation(summary = "分页查询MCP工具", description = "分页查询MCP工具，支持名称和描述模糊搜索，按添加日期倒序排列")
    @GetMapping("/page")
    public RestVO<Map<String, Object>> pageMcp(
            @RequestParam(defaultValue = "") String keyword,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        try {
            Page<AiMcp> resultPage = aiMcpService.pageQuery(keyword, page, size);
            Map<String, Object> result = new HashMap<>();
            result.put("total", resultPage.getTotal());
            result.put("pages", resultPage.getPages());
            result.put("current", resultPage.getCurrent());
            result.put("size", resultPage.getSize());
            result.put("records", resultPage.getRecords());
            return RestVO.success(result);
        } catch (Exception e) {
            return RestVO.fail("分页查询失败: " + e.getMessage());
        }
    }

    /**
     * 获取MCP配置状�?- Spring AI 1.0.0完整版本
     *
     * @return 配置状态信�?
     **/
    @Operation(summary = "获取MCP配置状", description = "返回当前MCP工具的配置模式、工具数量、可用工具列表等状态信息")
    @GetMapping("/status")
    public RestVO<Map<String, Object>> getStatus() {
        Map<String, Object> status = new HashMap<>();
        
        try {
            // 获取所有启用的工具回调
            List<ToolCallback> allTools = dynamicMcpClientManager.getAvailableToolCallbacks(true);
            
            // 按服务器分组统计
            Map<String, Integer> serverToolCounts = new HashMap<>();
            for (ToolCallback tool : allTools) {
                String serverName = dynamicMcpClientManager.getServerNameForTool(tool.getToolDefinition().name());
                serverToolCounts.put(serverName, serverToolCounts.getOrDefault(serverName, 0) + 1);
            }
            
            status.put("toolCount", allTools.size());
            status.put("serverCount", serverToolCounts.size());
            status.put("serverToolCounts", serverToolCounts);
            status.put("hasDynamicManager", true);
            status.put("tools", allTools.stream().map(tool -> {
                Map<String, Object> toolInfo = new HashMap<>();
                toolInfo.put("name", tool.getToolDefinition().name());
                toolInfo.put("description", tool.getToolDefinition().description());
                toolInfo.put("server", dynamicMcpClientManager.getServerNameForTool(tool.getToolDefinition().name()));
                return toolInfo;
            }).toList());
            
            logger.debug("📊 状态查询?- 共{}个服务器，{}个工具", serverToolCounts.size(), allTools.size());
            
            return RestVO.success(status);
        } catch (Exception e) {
            logger.error("获取MCP状态失败", e);
            return RestVO.fail("获取MCP状态失败 " + e.getMessage());
        }
    }

    /**
     * 获取可用工具列表 - Spring AI 1.0.0完整版本
     *
     * @return 工具列表
     */
    @Operation(summary = "获取可用MCP工具列表", description = "返回当前可用的MCP工具及其描述、输入参数等信息")
    @GetMapping("/tools")
    public RestVO<Map<String, Object>> getTools() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 获取所有启用的工具回调
            List<ToolCallback> allTools = dynamicMcpClientManager.getAvailableToolCallbacks(true);
            
            // 转换为详细信�?
            List<Map<String, Object>> toolDetails = new ArrayList<>();
            for (ToolCallback tool : allTools) {
                Map<String, Object> toolInfo = new HashMap<>();
                toolInfo.put("name", tool.getToolDefinition().name());
                toolInfo.put("description", tool.getToolDefinition().description());
                toolInfo.put("server", dynamicMcpClientManager.getServerNameForTool(tool.getToolDefinition().name()));
                toolInfo.put("inputSchema", dynamicMcpClientManager.getInputSchemaForTool(tool.getToolDefinition().name()));
                toolDetails.add(toolInfo);
            }
            
            result.put("success", true);
            result.put("toolCount", allTools.size());
            result.put("tools", toolDetails);
            
            return RestVO.success(result);
        } catch (Exception e) {
            logger.error("�?获取工具列表失败", e);
            return RestVO.fail("获取工具列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取指定MCP工具列表 - Spring AI 1.0.0完整版本
     *
     * @return 工具列表
     */
    @Operation(summary = "获取指定MCP工具列表", description = "返回当前MCP服务的工具及其描述、输入参数等信息")
    @GetMapping("/toolsByName")
    public RestVO<Map<String, Object>> toolsByName(@RequestParam String mcpName) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 获取指定服务器的工具
            List<ToolCallback> serverTools = dynamicMcpClientManager.getToolsForServer(mcpName);
            
            // 转换为详细信�?
            List<Map<String, Object>> toolDetails = new ArrayList<>();
            for (ToolCallback tool : serverTools) {
                Map<String, Object> toolInfo = new HashMap<>();
                toolInfo.put("name", tool.getToolDefinition().name());
                toolInfo.put("description", tool.getToolDefinition().description());
                toolInfo.put("server", mcpName);
                toolInfo.put("inputSchema", dynamicMcpClientManager.getInputSchemaForTool(tool.getToolDefinition().name()));
                toolDetails.add(toolInfo);
            }
            
            result.put("success", true);
            result.put("toolCount", serverTools.size());
            result.put("tools", toolDetails);
            
            logger.debug("🔧 指定工具查询 - {}服务器有{}个工具", mcpName, serverTools.size());
            return RestVO.success(result);
        } catch (Exception e) {
            logger.error("获取指定服务器工具列表失败", e);
            return RestVO.fail("获取指定服务器工具列表失�? " + e.getMessage());
        }
    }

    /**
     * 刷新工具列表 - Spring AI 1.0.0完整版本
     *
     * @return 刷新结果
     */
    @Operation(summary = "刷新MCP工具列表", description = "重新从MCP服务器获取工具列表并刷新缓存")
    @PostMapping("/refresh")
    public RestVO<Map<String, Object>> refreshTools() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 刷新所有客户端
            dynamicMcpClientManager.refreshAllClients();
            
            // 获取刷新后的工具数量
            List<ToolCallback> allTools = dynamicMcpClientManager.getAvailableToolCallbacks(true);
            
            result.put("success", true);
            result.put("message", "工具列表刷新成功");
            result.put("toolCount", allTools.size());
            
            logger.info("🔄 工具列表刷新成功，共{}个工具", allTools.size());
            
            return RestVO.success(result);
        } catch (Exception e) {
            logger.error("�?刷新工具列表失败", e);
            return RestVO.fail("刷新工具列表失败: " + e.getMessage());
        }
    }

    /**
     * 新增MCP工具
     */
    @Operation(summary = "新增MCP工具", description = "新增一条MCP工具记录")
    @PostMapping("/entity")
    public RestVO<String> addMcp(@RequestBody AiMcp mcp) {
        try {
            aiMcpService.addMcp(mcp);
            // 新增后刷新客户端
            dynamicMcpClientManager.refreshAllClients();
            return RestVO.success("新增成功");
        } catch (Exception e) {
            return RestVO.fail("新增失败: " + e.getMessage());
        }
    }

    /**
     * 启用/禁用MCP服务
     * @param params 包含id和enable参数的Map
     * @return 操作结果
     */
    @Operation(summary = "启用/禁用MCP服务", description = "根据传入的id和enable参数启用或禁用指定的MCP服务")
    @PutMapping("/enable")
    public RestVO<String> updateMcpEnableStatus(@RequestBody Map<String, Object> params) {
        try {
            Long id = Long.valueOf(params.get("id").toString());
            Integer enable = Integer.valueOf(params.get("enable").toString());
            
            aiMcpService.updateMcpEnableStatus(id, enable);
            // 更新启用状态后刷新客户�?
            dynamicMcpClientManager.refreshAllClients();
            
            String action = enable == 1 ? "启用" : "禁用";
            logger.info("MCP服务{}成功，ID: {}", action, id);
            return RestVO.success(action + "成功");
        } catch (Exception e) {
            logger.error("更新MCP服务启用状态失", e);
            return RestVO.fail("操作失败: " + e.getMessage());
        }
    }

    /**
     * 手动重连MCP服务
     * @param serverName 要重连的服务器名，不传则重连所�?     * @return 操作结果
     */
    @PostMapping("/reconnect")
    @Operation(summary = "手动重连MCP服务", description = "手动触发重连指定的MCP服务，如果不传参数则重连所有失联的MCP服务")
    public RestVO<String> reconnectMcp(@RequestParam(required = false) String serverName) {
        try {
            // 刷新所有客户端
            dynamicMcpClientManager.refreshAllClients();
            
            if (serverName == null || serverName.trim().isEmpty()) {
                return RestVO.success("所有MCP服务重连成功");
            } else {
                return RestVO.success("MCP服务重连成功: " + serverName);
            }
        } catch (Exception e) {
            return RestVO.fail("重连失败: " + e.getMessage());
        }
    }

    /**
     * 获取当前活跃的MCP客户端列�?     * @return 活跃客户端列�?
     */
    @GetMapping("/active-clients")
    @Operation(summary = "获取活跃MCP客户", description = "获取当前所有活跃的MCP客户端列表")
    public RestVO<List<String>> getActiveClients() {
        try {
            // 获取所有启用的工具回调
            List<ToolCallback> allTools = dynamicMcpClientManager.getAvailableToolCallbacks(true);
            
            // 提取服务器名�?
            Set<String> serverNames = new HashSet<>();
            for (ToolCallback tool : allTools) {
                String serverName = dynamicMcpClientManager.getServerNameForTool(tool.getToolDefinition().name());
                serverNames.add(serverName);
            }
            
            return RestVO.success(new ArrayList<>(serverNames));
        } catch (Exception e) {
            return RestVO.fail("获取活跃客户端失�? " + e.getMessage());
        }
    }
}
